﻿/**
 * 标题栏类的构造方法。
 * @param height    高度
 * @param parent    父窗口
 * @param title     标题
 * @retrun 标题栏
 */
function TitleBar(height, parent, title) {
    var mMoveing = false    // 移动标志
    var mPreviousX = 0      // 移动中上一个点的 X 坐标
    var mPreviousY = 0      // 移动中上一个点的 Y 坐标

    // 设置标题栏
    const titleBar = document.createElement("div")  // 标题栏
    titleBar.style.fontSize = "12px"
    titleBar.style.lineHeight = height + "px"
    titleBar.innerHTML = "&nbsp" + title
    titleBar.style.border = "1px solid gray"
    titleBar.style.background = "-webkit-linear-gradient(bottom, white, lightYellow)"
    titleBar.style.position = "absolute"
    titleBar.style.left = "1px"
    titleBar.style.top = "0px"
    titleBar.style.width = parent.clientWidth - 4 + "px"
    titleBar.style.height = height + "px"
    parent.appendChild(titleBar)

    // 设置关闭按钮
    const margin = 3
    var buttonX_height = height - margin * 2
    var buttonX_width = buttonX_height
    const buttonX = document.createElement("button")
    buttonX.onclick = function() {
        parent.style.display = "none"
    }
    buttonX.style.background = "-webkit-linear-gradient(bottom, white, lightYellow)"
    buttonX.style.position = "absolute"
    buttonX.style.width = buttonX_width + "px"
    buttonX.style.height = buttonX_height + "px"
    buttonX.style.left = parent.clientWidth - buttonX_width - margin * 2 + "px"
    buttonX.style.top = margin + "px"
    buttonX.style.padding = "0px"
    buttonX.style.display = "block"
    buttonX.innerHTML = "❌"
    parent.appendChild(buttonX)

    /**
     * 鼠标左键按下事件的响应方法。
     * @param e 事件相关信息
     */
    titleBar.onmousedown = function(e) {
        mMoveing = true
        mPreviousX = e.x
        mPreviousY = e.y
    }

    /**
     * 鼠标移动事件的响应方法。
     * @param e 事件相关信息
     */
    titleBar.onmousemove = function(e) {
        if (mMoveing) {
            parent.x += (e.x - mPreviousX)
            parent.y += (e.y - mPreviousY)
            parent.style.left = parent.x + "px"
            parent.style.top = parent.y + "px"
            mPreviousX = e.x
            mPreviousY = e.y
        }
    }

    /**
     * 鼠标离开事件的响应方法。
     */
    titleBar.onmouseout = function() {
        mMoveing = false
    }

    /**
     * 鼠标左键抬起事件的响应方法。
     */
    titleBar.onmouseup = function() {
        mMoveing = false
    }

    /**
     * 鼠标指针按下事件的响应方法。
     * @param e 事件相关信息
     */
    titleBar.onpointerdown = function(e) {
        titleBar.setPointerCapture(e.pointerId)
    }

    /**
     * 鼠标指针抬起事件的响应方法。
     * @param e 事件相关信息
     */
    titleBar.onpointerup = function(e) {
        titleBar.releasePointerCapture(e.pointerId)
    }

    return titleBar 
}

/**
 * 聊天窗口类的构造方法。
 * @param parent    父窗口
 * @param username  用户名
 */
function ChatWindow(parent, username) {
    const mDialog = document.createElement("div")               // 对话框
    const mEditHistory = document.createElement("textarea")     // 聊天历史编辑框
    const mEditInput = document.createElement("textarea")       // 聊天内容编辑框
    const mEventChatC2S = document.createEvent("customEvent")   // 聊天事件（客户端到服务器）

    // 初始化事件
    mEventChatC2S.initEvent(Const.UM_CHAT_C2S, false, false)

    // 设置对话框
    mDialog.style.position = "absolute"
    mDialog.style.width = Const.CHAT_WINDOW_WIDTH + "px"
    mDialog.style.height = Const.CHAT_WINDOW_HEIGHT + "px"
    mDialog.x = (parent.clientWidth - Const.CHAT_WINDOW_WIDTH) / 2
    mDialog.y = (parent.clientHeight - Const.CHAT_WINDOW_HEIGHT) / 2
    mDialog.style.left = mDialog.x + "px"
    mDialog.style.top = mDialog.y + "px"
    mDialog.style.display = "block"
    parent.appendChild(mDialog)

    // 设置标题栏
    new TitleBar(Const.CHAT_WINDOW_TITLE_BAR_HEIGHT, mDialog, username)

    // 设置聊天历史编辑框
    mEditHistory.readOnly = true
    mEditHistory.style.position = "absolute"
    mEditHistory.style.width = Const.CHAT_WINDOW_EDIT_HISTORY_WIDTH + "px"
    mEditHistory.style.height = Const.CHAT_WINDOW_EDIT_HISTORY_HEIGHT + "px"
    mEditHistory.style.left = Const.CHAT_WINDOW_EDIT_HISTORY_X + "px"
    mEditHistory.style.top = Const.CHAT_WINDOW_EDIT_HISTORY_Y + "px"
    mEditHistory.style.display = "block"
    mDialog.appendChild(mEditHistory)

    // 设置聊天内容编辑框
    mEditInput.style.position = "absolute"
    mEditInput.style.width = Const.CHAT_WINDOW_EDIT_INPUT_WIDTH + "px"
    mEditInput.style.height = Const.CHAT_WINDOW_EDIT_INPUT_HEIGHT + "px"
    mEditInput.style.left = Const.CHAT_WINDOW_EDIT_INPUT_X + "px"
    mEditInput.style.top = Const.CHAT_WINDOW_EDIT_INPUT_Y + "px"
    mEditInput.style.display = "block"
    mDialog.appendChild(mEditInput)
    mEditInput.maxLength = Const.MAX_CONTENT_LEN    // 设置最大输入长度
    mEditInput.focus()

    // 设置"发送"按钮
    const buttonSend = document.createElement("button")
    buttonSend.style.position = "absolute"
    buttonSend.style.width = Const.CHAT_WINDOW_BUTTON_SEND_WIDTH + "px"
    buttonSend.style.height = Const.CHAT_WINDOW_BUTTON_SEND_HEIGHT + "px"
    buttonSend.style.left = Const.CHAT_WINDOW_BUTTON_SEND_X + "px"
    buttonSend.style.top = Const.CHAT_WINDOW_BUTTON_SEND_Y + "px"
    buttonSend.style.display = "block"
    buttonSend.innerHTML = IDS_SEND[LANG]
    buttonSend.onclick = onButtonSendClicked
    mDialog.appendChild(buttonSend)

    /**
     * 隐藏自身。
     */
    this.hide = function() {
        mDialog.style.display = "none"
    }

    /**
     * "发送"按钮的单击响应方法。
     */
    function onButtonSendClicked() {
        // 获取用户输入的聊天内容
        const content = mEditInput.value

        // 获取当前时间
        const time = new Date().toLocaleString()

        // 显示聊天内容
        const chatInfo = new ChatInfo(content, username, Client.sUsername, time)
        setContent(chatInfo)

        // 清空聊天内容编辑框
        mEditInput.value = ""

        // 发送聊天信息
        mEventChatC2S.arg1 = chatInfo
        document.dispatchEvent(mEventChatC2S)
    }

    /**
     * 设置聊天内容。
     * @param chatInfo  聊天信息
     */
    function setContent(chatInfo) {
        // 显示聊天内容
        const content = chatInfo.mSrcUsername + Const.LEFT_BR + chatInfo.mTime + Const.RIGHT_BR + chatInfo.mContent + Const.WRAP
        mEditHistory.value += content
        
        // 滚动到最底行
        mEditHistory.scrollTo(0, mEditHistory.clientHeight)
    }
    this.setContent = setContent

    /**
     * 显示。
     */
    this.show = function() {
        mDialog.style.display = "block"
    }
}
